/**
  ******************************************************************************
  * @file           : studio_color.cpp
  * @author         : wangyingjie
  * @brief          : None
  * @attention      : None
  * @date           : 2025/6/4
  ******************************************************************************
  */

#include "studio_color.h"

#define MAX_ENCODE_V 12799.9999
#define MIN_ENCODE_V (-12799.9999)

int studio_color::channels(const studio_color::type& t)
{
    switch (t)
    {
        case eptRGB:
            return 3;
        case eptRGBA:
            return 4;
        case eptGRAY:
            return 1;
        case eptGRAYA:
            return 2;
        default:
            return 0;
    }
}

bool studio_color::hex2argb(const char* color)
{
    unsigned int v = 0;
    if (1 != sscanf(color, "%x", &v) || strlen(color) != 8)
    {
        return false;
    }
    // 或者 左移然后 和 0xFF 做与
    blue = (v << 24) >> 24;
    green = (v << 16) >> 24;
    red = (v << 8) >> 24;
    alpha = v >> 24;

    return true;
}

bool studio_color::hex2rgb(const char* color)
{
    unsigned int v = 0;
    if (1 != sscanf(color, "%x", &v) || strlen(color) != 6)
    {
        return false;
    }
    blue = (v << 16) >> 16;
    green = (v << 8) >> 16;
    red = v >> 16;
    return true;
}

bool studio_color::hex2rgba(const char* color)
{
    unsigned int v = 0;
    if (1 != sscanf(color, "%x", &v) || strlen(color) != 8)
    {
        return false;
    }
    alpha = (v << 24) >> 24;
    blue = (v << 16) >> 24;
    green = (v << 8) >> 24;
    red = v >> 24;
    return true;
}

double studio_color::vdecode() const
{
    double ret = 0;
    ret += red * 1.e2;
    ret += green;
    ret += blue / 100.0;
    ret += alpha / 10000.0;
    return ret + MIN_ENCODE_V;
}

void studio_color::vencode(const double& vv)
{
    double v = vv - MIN_ENCODE_V;
    red = static_cast<unsigned char>(static_cast<int>(v / 1e2));
    green = static_cast<unsigned char>(static_cast<int>(v) % 100);
    blue = static_cast<unsigned char>(static_cast<int>(v * 100) % 100);
    alpha = static_cast<unsigned char>(static_cast<int>(v * 10000) % 100);
}

std::string studio_color::argb2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << alpha;
    oss << std::setw(2) << red;
    oss << std::setw(2) << green;
    oss << std::setw(2) << blue;
    return oss.str();
}

std::string studio_color::rgb2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << red;
    oss << std::setw(2) << green;
    oss << std::setw(2) << blue;
    return oss.str();
}

std::string studio_color::rgba2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << red;
    oss << std::setw(2) << green;
    oss << std::setw(2) << blue;
    oss << std::setw(2) << alpha;
    return oss.str();
}

std::string studio_color::abgr2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << alpha;
    oss << std::setw(2) << blue;
    oss << std::setw(2) << green;
    oss << std::setw(2) << red;
    return oss.str();
}

std::string studio_color::bgra2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << blue;
    oss << std::setw(2) << green;
    oss << std::setw(2) << red;
    oss << std::setw(2) << alpha;
    return oss.str();
}

std::string studio_color::bgr2hex() const
{
    std::ostringstream oss;
    oss << std::uppercase << std::hex << std::setfill('0');
    oss << std::setw(2) << blue;
    oss << std::setw(2) << green;
    oss << std::setw(2) << red;
    return oss.str();
}